package com.googlecode.dgwt.client.dijit.base.state;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Event;
import com.googlecode.dgwt.client.dijit.Dijit;
import com.googlecode.dgwt.client.dijit.Widget;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class ActiveState extends EventState {
    
    private static ActiveState instance;
    
    private Widget activeWidget;
    
    
    public static ActiveState get() {
        if (instance == null) {
            instance = new ActiveState();
        }
        return instance;
    }
    
    
    private ActiveState() {
        final Command handler = new Command() {
            @Override
            public void execute() {
                activeWidget = null;
            }
        };
        
        DeferredCommand.addCommand(new Command() {
            
            @Override
            public void execute() {
                setup(handler);
            }
            
            //TODO encontrar um outro modo de anexar eventos em $doc.body
            public native void setup(Command handler) /*-{
                var setup;
                setup = function(){
                    if (@com.googlecode.dgwt.client.dijit.Dijit::isLoaded()()){
                        dojo.connect($doc.body, "onmouseup", function(){
                            handler.@com.google.gwt.user.client.Command::execute()();
                        });
                    } else {
                        setTimeout(setup, 50);
                    }
                };
                setup();
            }-*/;
            
        });
    }
    
    @Override
    public boolean isActivatedBy(Event event, int eventMask, Widget widget) {
        boolean isMouseDown = (eventMask & Event.ONMOUSEDOWN) != 0;
        if (isMouseDown) {
            if (activeWidget != null){
                // if active widget is parent of new widget maintain it
                if (activeWidget.getElement().isOrHasChild(widget.getElement())){
                    return true;
                }
            }
            activeWidget = widget;
            return true;
        }
        return widget.equals(activeWidget) && HoverState.get().isActivatedBy(event, eventMask, widget);
    }
    
    @Override
    public boolean isDeactivatedBy(Event event, int eventMask, Widget widget) {
        return ((eventMask & Event.ONMOUSEUP) != 0) || HoverState.get().isDeactivatedBy(event, eventMask, widget);
    }
    
    @Override
    protected String getDependentStyleClass() {
        return Dijit.getTheme().getActiveName();
    }

    @Override
    public int getEventMask() {
        return Event.ONMOUSEDOWN | Event.ONMOUSEOVER | Event.ONMOUSEUP | Event.ONMOUSEOUT;
    }

    public Widget getActiveWidget() {
        return activeWidget;
    }

}
